﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using BusinessRule.Common;
using BusinessRule.Business;
using BusinessRule.DTO;
using DatabaseAccess.DBUtility;
using System.Threading.Tasks;
using System.Configuration;

//Description:热表滚动制造计划定时任务处理类
//Copyright (c) : 通力凯顿（北京）系统集成有限公司
//Writer:zhangrj
//create Date:2024-09-29
//Rewriter:
//Rewrite Date:

namespace MESScheduledTask
{
    public class RbApsScheduledTask
    {
        private LimitedCapacityBusiness m_LMObj = new LimitedCapacityBusiness();
        private RbApsLimitedCapacityBusiness rbAps = new RbApsLimitedCapacityBusiness();
        public static readonly int maxParallelSync = Convert.ToInt32(ConfigurationManager.AppSettings["maxParallelSync"].ToString());//最大并行任务数

        /// <summary>
        /// 执行任务
        /// </summary>
        /// <param name="taskList"></param>
        public void RunTaskSync(List<string> taskList)
        {
            //获取需要启动的任务
            DataTable dt = CommonHelper.GetNeedExecuteTask(CommonHelper.TaskTypeEnum.滚动制造计划_工步);
            List<Task> tl = new List<Task>();
            foreach (DataRow dr2 in dt.Rows)
            {//开始循环定时任务
                var tempDt = dt.Clone();
                tempDt.ImportRow(dr2);
                var dr = tempDt.Rows[0];//此处必须要给局部变量赋值

                if (taskList.Count >= maxParallelSync)
                {
                    LogHelp.WriteLog("当前正在执行的任务数为：" + taskList.Count.ToString() + " 已达到最大并行限制----------------------------------------------------------------------");
                    break;
                }
                if (taskList.Contains(dr["scheduledtaskid"].ToString()))//已在任务中
                    continue;

                taskList.Add(dr["scheduledtaskid"].ToString());//添加到list中

                tl.Add(Task.Factory.StartNew(() =>
                {
                    try
                    {
                        DealRbApsTask(dr);
                    }
                    catch (Exception ex)
                    {
                        LogHelp.WriteError(dr["taskname"].ToString() + "定时计算异常", ex);
                        CommonHelper.WriteTaskLog(dr["ScheduledTaskId"].ToString(), "3", ex.Message + ex.StackTrace, "1");
                        return;
                    }
                    finally
                    {
                        LogHelp.WriteLog("任务：" + dr["taskname"].ToString() + " " + dr["taskdesc"].ToString() + " 执行完毕，移除队列");
                        taskList.Remove(dr["scheduledtaskid"].ToString());
                    }
                }, TaskCreationOptions.LongRunning));

            }
            //本次产生的task，需要等待完毕
            Task.WaitAll(tl.ToArray());
        }

        /// <summary>
        /// 处理单个任务
        /// </summary>
        /// <param name="dr"></param>
        public void DealRbApsTask(DataRow dr)
        {
            if (dr["type"].ToString() == "自动未执行")
            {
                CommonHelper.WriteTaskLog(dr["ScheduledTaskId"].ToString(), "2", "", "1");//开始执行
            }
            Dictionary<string, string> dicAttr = CommonHelper.GetTaskAttr(dr["ScheduledTaskId"].ToString());//获取定时任务的属性
            /*定义参数*/
            int scount = 0, ecount = 0;//成功条数，失败条数
            string msg = string.Empty;//提示消息
            int coverCycle = int.Parse(dicAttr["覆盖周期"]);
            //获取排产池
            DataTable dtPool = m_LMObj.GetPoolList(new Dictionary<string, string> { { "FactoryID", dr["factoryid"].ToString() } });
            /*先计算优先级，如果报错，也要执行排产计算*/
            try
            {
                if (!rbAps.CalcContainerApsPriority(new Dictionary<string, string> {
                                        {"PoolID",dtPool.Rows[0]["apspoolid"].ToString()},
                                        { "IsPaging", "false" },//不分页
                                        { "IsAps", "1" },//不包含已经排产的数据
                                        { "IsContinuityContainer", "1" } //不查询处于连续批次中的非首位批次
                                        }, ref msg))
                {
                    LogHelp.WriteLog(string.Format("分厂：热表，任务：{0} 计算优先级出错，原因：{1}", dr["taskname"].ToString(), msg));
                    //CommonHelper.WriteTaskLog(dr["ScheduledTaskId"].ToString(), "4", " 任务执行完毕，计算优先级出错，原因：" + msg, "1");
                    //return;
                }
            }
            catch (Exception e) {
                LogHelp.WriteLog(string.Format("分厂：热表，任务：{0} 计算优先级出错，原因：{1}", dr["taskname"].ToString(), e.Message));
            }
            /*获取热表可排产的批次数据*/
            uMESProcessResult result = rbAps.GetApsPlanContainerData(new Dictionary<string, string> {
                                        { "IsPaging", "false" },//不分页
                                        { "IsAps", "1" },//不包含已经排产的数据
                                        { "IsContinuityContainer", "1" } //不查询处于连续批次中的非首位批次
                                        });
            if (!result.Result)
            {
                LogHelp.WriteLog(string.Format("分厂：热表，任务：{0} 查询滚动制造计划数据报错，原因：{1}", dr["taskname"].ToString(), result.Message));
                CommonHelper.WriteTaskLog(dr["ScheduledTaskId"].ToString(), "4", " 任务执行完毕，查询滚动制造计划数据报错，原因：" + result.Message, "1");
                return;
            }
            DataTable dtAps = result.DBTable;
            LogHelp.WriteLog(string.Format("分厂：热表，任务：{0}开始执行，执行滚动制造计划总数：{1}-------------------------------------------------------------", dr["taskname"].ToString(), dtAps.Rows.Count));
            CommonHelper.UpdateTaskLogStartDate(dr["ScheduledTaskId"].ToString()); //更新定时任务日志的开始时间为当前时间
            CurrentUserInfo user = new CurrentUserInfo();

            /*开始循环执行数据*/
            for (int i = 0; i < dtAps.Rows.Count; i++)
            {
                //检查是否提前终止
                if (DatabaseHelper.GetSingle(string.Format(@"select 1 from ScheduledTaskLogs sl
                                        where sl.scheduledtaskid='{0}' and sl.islatest=1 and sl.taskexeendtime is not null", dr["ScheduledTaskId"].ToString())) != null)
                {
                    break;
                }
                DataRow drAps = dtAps.Rows[i];
                if (DatabaseHelper.GetSingle(string.Format("SELECT 1 FROM apsplandetail apd WHERE apd.containerid = '{0}'", drAps["containerid"].ToString())) != null)
                {
                    ecount++;
                    LogHelp.WriteLog(string.Format("分厂：热表，任务：{0} 的第{1}个批次：{2}，已工序排产，跳过工步排产", dr["taskname"].ToString(), (i + 1).ToString(), drAps["containername"].ToString()));
                    continue;
                }
                DataTable dtSingAps = dtAps.Clone();
                dtSingAps.ImportRow(drAps);
                result = rbAps.CalcContainersApsPlan(dtSingAps, user);//计算批次排产
                if (result.Result)
                {
                    LogHelp.WriteLog(string.Format("分厂：热表，任务：{0} 的第{1}个批次：{2}计算成功", dr["taskname"].ToString(), (i + 1).ToString(), drAps["containername"].ToString()));
                }
                else
                {
                    LogHelp.WriteLog(string.Format("分厂：热表，任务：{0} 的第{1}个批次：{2}计算失败，{3}", dr["taskname"].ToString(), (i + 1).ToString(), drAps["containername"].ToString(), result.Message));
                }
            }
            //此任务执行完毕
            CommonHelper.WriteTaskLog(dr["ScheduledTaskId"].ToString(), "4", string.Format(" 任务执行完毕，执行滚动制造计划数：{0}", dtAps.Rows.Count), "1");
            LogHelp.WriteLog(string.Format("分厂：热表，任务：{0} 执行完毕----------------------------------------------------------------------", dr["taskname"].ToString()));
        }
    }
}
